home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / src / syslog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-24  |  6.3 KB  |  270 lines

  1. /*
  2.  * Copyright (c) 1983, 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. /*
  19.  * SYSLOG -- print message on log file
  20.  *
  21.  * This routine looks a lot like printf, except that it outputs to the
  22.  * log file instead of the standard output.  Also:
  23.  *    adds a timestamp,
  24.  *    prints the module name in front of the message,
  25.  *    has some other formatting types (or will sometime),
  26.  *    adds a newline on the end of the message.
  27.  *
  28.  * The output of this routine is intended to be read by syslogd(8).
  29.  *
  30.  * Author: Eric Allman
  31.  * Modified to use UNIX domain IPC by Ralph Campbell
  32.  * modified for System V by Bruce Lilly
  33.  */
  34.  
  35. #include "sendmail.h"
  36. #ifdef NEED_SYSLOG
  37.  
  38. # if defined(LIBC_SCCS) && !defined(lint)
  39. static char sccsid[] = "@(#)syslog.c    5.20 (Berkeley) 1/19/89";
  40. # endif /* LIBC_SCCS and not lint */
  41.  
  42. # ifdef SYSV
  43. #  include <string.h>
  44. # else /* !SYSV */
  45. #  include <strings.h>
  46. # endif /* SYSV */
  47. # include <netdb.h>
  48.  
  49. # ifdef __STDC__
  50. void    closelog();
  51. # else /* !__STDC__ */
  52. void    closelog(), vsyslog();
  53. # endif /* __STDC__ */
  54.  
  55. # define    LOGNAME    "/dev/log"
  56. # define    CONSOLE    "/dev/console"
  57.  
  58. static int    LogFile = -1;        /* fd for log */
  59. static int    connected;        /* have done connect */
  60. static int    LogStat = 0;        /* status bits, set by openlog() */
  61. static char    *LogTag = "syslog";    /* string to tag the entry with */
  62. static int    LogFacility = LOG_USER;    /* default facility code */
  63.  
  64. # ifndef __STDC__
  65. void
  66. syslog(pri, fmt, args)
  67.     int pri, args;
  68.     char *fmt;
  69. {
  70.     vsyslog(pri, fmt, &args);
  71. }
  72.  
  73. /*VARARGS2*/
  74. void
  75. vsyslog(pri, fmt, va_alist)
  76.     int pri;
  77.     register char *fmt;
  78.     va_dcl
  79. # else /* __STDC__ */
  80.  
  81. void
  82. syslog(int pri, char *fmt, ...)
  83. # endif /* !__STDC__ */
  84.       va_list ap;
  85.     extern int errno;
  86.     register int cnt;
  87.     register char *p;
  88.     time_t now;
  89.     int pid, saved_errno;
  90.     char tbuf[2048], fmt_cpy[1024];
  91.     unsigned int more_time;
  92.  
  93. # ifdef __STDC__
  94.     va_start(ap, fmt);
  95. # else /* !__STDC__ */
  96.     va_start(ap);
  97. # endif /* __STDC__ */
  98.     saved_errno = errno;
  99.  
  100.     /* see if we should just throw out this message */
  101.     if ((u_int)LOG_FAC(pri) >= LOG_NFACILITIES ||
  102.         !LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
  103.     {
  104.         va_end(ap);
  105.         return;
  106.     }
  107.     if (LogFile < 0 || !connected)
  108.         openlog(LogTag, LogStat | LOG_NDELAY, 0);
  109.  
  110.     /* set default facility if none specified */
  111.     if ((pri & LOG_FACMASK) == 0)
  112.         pri |= LogFacility;
  113.  
  114.     /* build the message */
  115.     (void)time(&now);
  116.     (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
  117.     for (p = tbuf; *p; ++p);
  118.     if (LogTag) {
  119.         (void)strcpy(p, LogTag);
  120.         for (; *p; ++p);
  121.     }
  122.     if (LogStat & LOG_PID) {
  123.         (void)sprintf(p, "[%d]", getpid());
  124.         for (; *p; ++p);
  125.     }
  126.     if (LogTag) {
  127.         *p++ = ':';
  128.         *p++ = ' ';
  129.     }
  130.  
  131.     /* substitute error message for %m */
  132.     {
  133.         register char ch, *t1, *t2;
  134.  
  135.         for (t1 = fmt_cpy; ch = *fmt; ++fmt)
  136.             if (ch == '%' && fmt[1] == 'm') {
  137.                 ++fmt;
  138.                 for (t2 = strerror(saved_errno);
  139.                     *t1 = *t2++; ++t1);
  140.             }
  141.             else
  142.                 *t1++ = ch;
  143.         *t1 = '\0';
  144.     }
  145.  
  146.     (void)vsprintf(p, fmt_cpy, ap);
  147.     va_end(ap);
  148.  
  149.     /* output the message to the local logger */
  150.     if (send(LogFile, tbuf, cnt = strlen(tbuf), 0) >= 0 ||
  151.         !(LogStat&LOG_CONS))
  152.         return;
  153.  
  154.     /* output the message to the console */
  155.     pid = vfork();
  156.     if (pid == -1)
  157.         return;
  158.     if (pid == 0) {
  159.         int fd;
  160.  
  161.         (void)signal(SIGALRM, SIG_DFL);
  162. # ifndef SYSV
  163.         sigsetmask((long)~sigmask(SIGALRM));
  164. # endif /* !SYSV */
  165.         more_time = 5;
  166.         while (more_time = alarm(more_time))
  167.             ;
  168.         if ((fd = open(CONSOLE, O_WRONLY, 0)) < 0)
  169.             return;
  170.         (void)alarm((u_int)0);
  171.         (void)strcat(tbuf, "\r");
  172.         p = index(tbuf, '>') + 1;
  173.         (void)write(fd, p, cnt + 1 - (p - tbuf));
  174.         (void)close(fd);
  175.         _exit(0);
  176.     }
  177.     if (!(LogStat & LOG_NOWAIT))
  178.         while ((cnt = wait((int *)0)) > 0 && cnt != pid);
  179. }
  180.  
  181. static struct sockaddr SyslogAddr;    /* AF_UNIX address of local logger */
  182. static struct sockaddr_in SyslogPort;    /* AF_INET address of local logger */
  183. /*
  184.  * OPENLOG -- open system log
  185.  */
  186. void
  187. openlog(ident, logstat, logfac)
  188.     char *ident;
  189.     int logstat, logfac;
  190. {
  191.     if (ident != NULL)
  192.         LogTag = ident;
  193.     LogStat = logstat;
  194.     if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
  195.         LogFacility = logfac;
  196.     if (LogFile == -1) {
  197.         SyslogAddr.sa_family = AF_UNIX;
  198.         strncpy(SyslogAddr.sa_data, LOGNAME, sizeof SyslogAddr.sa_data);
  199.         if (LogStat & LOG_NDELAY) {
  200.             LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
  201.             fcntl(LogFile, F_SETFD, 1);
  202.         }
  203.     }
  204.     if (LogFile != -1 && !connected &&
  205.         connect(LogFile, &SyslogAddr, sizeof(SyslogAddr)) != -1) {
  206.         connected = 1;
  207.         return;
  208.     } else
  209.         if (LogFile != -1)
  210.             (void) close(LogFile);
  211.     if (LogFile == -1) {{
  212.         struct    servent    *se;
  213.         struct    hostent    *host = 0;
  214.         char    hbuf[32];
  215.  
  216.         if (gethostname(hbuf, 31) == 0) {
  217.             strtok(hbuf, ".");
  218.             host = gethostbyname(hbuf);
  219.         }
  220.         if (host == NULL)
  221.             if ((host = gethostbyname("localhost")) == NULL)
  222.                 return;
  223.         if((se = getservbyname("syslog", "udp")) == NULL)
  224.             return;
  225.         SyslogPort.sin_port = se->s_port;
  226.         SyslogPort.sin_family = AF_INET;
  227.         if((LogFile = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  228.             return;
  229.         (void) memcpy((caddr_t)&SyslogPort.sin_addr, (caddr_t)host->h_addr,
  230.             host->h_length);
  231.     }
  232.     if (LogFile != -1 && !connected &&
  233.         connect(LogFile, (struct sockaddr *)&SyslogPort, (int)sizeof(SyslogPort)) != -1) {
  234.         connected = 1;
  235.         return;
  236.     } else {
  237.         LogStat |= LOG_CONS;
  238.         if (LogFile != -1)
  239.             (void) close(LogFile);
  240.     }
  241. }
  242.  
  243. /*
  244.  * CLOSELOG -- close the system log
  245.  */
  246. void
  247. closelog()
  248. {
  249.     (void) close(LogFile);
  250.     LogFile = -1;
  251.     connected = 0;
  252. }
  253.  
  254. static int    LogMask = 0xff;        /* mask of priorities to be logged */
  255. /*
  256.  * SETLOGMASK -- set the log mask level
  257.  */
  258. int
  259. setlogmask(pmask)
  260.     int pmask;
  261. {
  262.     int omask;
  263.  
  264.     omask = LogMask;
  265.     if (pmask != 0)
  266.         LogMask = pmask;
  267.     return (omask);
  268. }
  269. #endif /* NEED_SYSLOG */
  270.